using Microsoft.EntityFrameworkCore;
using ProcessManagementApi.DTO;
using ProcessManagementApi.Services;
using MESData.ErrorCode;
using MESData.Infrastucture;
using MESBaseis.Domain.ZSH;
using NPOI.XSSF.UserModel;
using NPOI.SS.UserModel;

namespace ProcessManagementApi.Services
{
    /// <summary>
    /// 工序分类服务实现
    /// </summary>
    public class ProcessCategoryService : IProcessCategoryService
    {
        private readonly MyDbcontext _context;

        public ProcessCategoryService(MyDbcontext context)
        {
            _context = context;
        }

        /// <summary>
        /// 分页查询工序分类
        /// </summary>
        /// <param name="queryDto">查询条件</param>
        /// <returns>分页结果</returns>
        public async Task<ApiPageing<ProcessCategoryResultDto>> GetProcessCategoriesAsync(ProcessCategoryQueryDto queryDto)
        {
            try
            {
                var query = _context.ZshProcessCategories
                    .Include(pc => pc.Processes)
                    .Where(pc => !pc.IsDeleted)
                    .AsQueryable();

                // 应用查询条件
                if (!string.IsNullOrEmpty(queryDto.NumberOrName))
                {
                    query = query.Where(pc => 
                        pc.ProcessCategoryNumber.Contains(queryDto.NumberOrName) ||
                        pc.ProcessCategoryName.Contains(queryDto.NumberOrName));
                }

                if (queryDto.IsActive.HasValue)
                {
                    query = query.Where(pc => pc.IsActive == queryDto.IsActive.Value);
                }

                // 获取总数
                var totalCount = await query.CountAsync();

                // 分页查询
                var processCategories = await query
                    .OrderBy(pc => pc.SortOrder)
                    .ThenBy(pc => pc.ProcessCategoryNumber)
                    .Skip((queryDto.PageIndex - 1) * queryDto.PageSize)
                    .Take(queryDto.PageSize)
                    .Select(pc => new ProcessCategoryResultDto
                    {
                        Id = pc.Id,
                        ProcessCategoryNumber = pc.ProcessCategoryNumber,
                        ProcessCategoryName = pc.ProcessCategoryName,
                        SortOrder = pc.SortOrder,
                        IsActive = pc.IsActive,
                        Remarks = pc.Remarks,
                        ProcessCount = pc.Processes.Count(p => !p.IsDeleted),
                        CreateTime = pc.CreateTime,
                        Creator = pc.Creator,
                        UpdateTime = pc.UpdateTime,
                        Updator = pc.Updator
                    })
                    .ToListAsync();

                var totalPage = (int)Math.Ceiling((double)totalCount / queryDto.PageSize);

                return new ApiPageing<ProcessCategoryResultDto>
                {
                    Code = ApiEnum.Success,
                    Msg = "查询成功",
                    TotaCount = totalCount,
                    TotaPage = totalPage,
                    PageData = processCategories
                };
            }
            catch (Exception ex)
            {
                return new ApiPageing<ProcessCategoryResultDto>
                {
                    Code = ApiEnum.Error,
                    Msg = $"查询失败：{ex.Message}",
                    Data = null,
                    TotaCount = 0,
                    TotaPage = 0,
                    PageData = null
                };
            }
        }

        /// <summary>
        /// 根据ID获取工序分类详情
        /// </summary>
        /// <param name="id">工序分类ID</param>
        /// <returns>工序分类详情</returns>
        public async Task<ApiResult<ProcessCategoryResultDto>> GetProcessCategoryByIdAsync(int id)
        {
            try
            {
                var processCategory = await _context.ZshProcessCategories
                    .Include(pc => pc.Processes)
                    .Where(pc => pc.Id == id && !pc.IsDeleted)
                    .Select(pc => new ProcessCategoryResultDto
                    {
                        Id = pc.Id,
                        ProcessCategoryNumber = pc.ProcessCategoryNumber,
                        ProcessCategoryName = pc.ProcessCategoryName,
                        SortOrder = pc.SortOrder,
                        IsActive = pc.IsActive,
                        Remarks = pc.Remarks,
                        ProcessCount = pc.Processes.Count(p => !p.IsDeleted),
                        CreateTime = pc.CreateTime,
                        Creator = pc.Creator,
                        UpdateTime = pc.UpdateTime,
                        Updator = pc.Updator
                    })
                    .FirstOrDefaultAsync();

                if (processCategory == null)
                {
                    return new ApiResult<ProcessCategoryResultDto>
                    {
                        Code = ApiEnum.NotFound,
                        Msg = "工序分类不存在",
                        Data = null
                    };
                }

                return new ApiResult<ProcessCategoryResultDto>
                {
                    Code = ApiEnum.Success,
                    Msg = "查询成功",
                    Data = processCategory
                };
            }
            catch (Exception ex)
            {
                return new ApiResult<ProcessCategoryResultDto>
                {
                    Code = ApiEnum.Error,
                    Msg = $"查询失败：{ex.Message}",
                    Data = null
                };
            }
        }

        /// <summary>
        /// 创建工序分类
        /// </summary>
        /// <param name="createDto">创建DTO</param>
        /// <returns>创建结果</returns>
        public async Task<ApiResult<ProcessCategoryResultDto>> CreateProcessCategoryAsync(ProcessCategoryCreateDto createDto)
        {
            try
            {
                // 检查编号是否重复
                var existingNumber = await _context.ZshProcessCategories
                    .AnyAsync(pc => pc.ProcessCategoryNumber == createDto.ProcessCategoryNumber && !pc.IsDeleted);

                if (existingNumber)
                {
                    return new ApiResult<ProcessCategoryResultDto>
                    {
                        Code = ApiEnum.Error,
                        Msg = "工序分类编号已存在",
                        Data = null
                    };
                }

                // 检查名称是否重复
                var existingName = await _context.ZshProcessCategories
                    .AnyAsync(pc => pc.ProcessCategoryName == createDto.ProcessCategoryName && !pc.IsDeleted);

                if (existingName)
                {
                    return new ApiResult<ProcessCategoryResultDto>
                    {
                        Code = ApiEnum.Error,
                        Msg = "工序分类名称已存在",
                        Data = null
                    };
                }

                var processCategory = new ProcessCategory
                {
                    ProcessCategoryNumber = createDto.ProcessCategoryNumber,
                    ProcessCategoryName = createDto.ProcessCategoryName,
                    SortOrder = createDto.SortOrder,
                    IsActive = createDto.IsActive,
                    Remarks = createDto.Remarks,
                    CreateTime = DateTime.Now,
                    Creator = "System", // 这里可以从当前用户上下文获取
                    IsDeleted = false
                };

                _context.ZshProcessCategories.Add(processCategory);
                await _context.SaveChangesAsync();

                var result = new ProcessCategoryResultDto
                {
                    Id = processCategory.Id,
                    ProcessCategoryNumber = processCategory.ProcessCategoryNumber,
                    ProcessCategoryName = processCategory.ProcessCategoryName,
                    SortOrder = processCategory.SortOrder,
                    IsActive = processCategory.IsActive,
                    Remarks = processCategory.Remarks,
                    ProcessCount = 0,
                    CreateTime = processCategory.CreateTime,
                    Creator = processCategory.Creator,
                    UpdateTime = processCategory.UpdateTime,
                    Updator = processCategory.Updator
                };

                return new ApiResult<ProcessCategoryResultDto>
                {
                    Code = ApiEnum.Success,
                    Msg = "创建成功",
                    Data = result
                };
            }
            catch (Exception ex)
            {
                return new ApiResult<ProcessCategoryResultDto>
                {
                    Code = ApiEnum.Error,
                    Msg = $"创建失败：{ex.Message}",
                    Data = null
                };
            }
        }

        /// <summary>
        /// 更新工序分类
        /// </summary>
        /// <param name="updateDto">更新DTO</param>
        /// <returns>更新结果</returns>
        public async Task<ApiResult<ProcessCategoryResultDto>> UpdateProcessCategoryAsync(ProcessCategoryUpdateDto updateDto)
        {
            try
            {
                var processCategory = await _context.ZshProcessCategories
                    .Include(pc => pc.Processes)
                    .FirstOrDefaultAsync(pc => pc.Id == updateDto.Id && !pc.IsDeleted);

                if (processCategory == null)
                {
                    return new ApiResult<ProcessCategoryResultDto>
                    {
                        Code = ApiEnum.NotFound,
                        Msg = "工序分类不存在",
                        Data = null
                    };
                }

                // 检查编号是否重复（排除自己）
                var existingNumber = await _context.ZshProcessCategories
                    .AnyAsync(pc => pc.ProcessCategoryNumber == updateDto.ProcessCategoryNumber && 
                                   pc.Id != updateDto.Id && !pc.IsDeleted);

                if (existingNumber)
                {
                    return new ApiResult<ProcessCategoryResultDto>
                    {
                        Code = ApiEnum.Error,
                        Msg = "工序分类编号已存在",
                        Data = null
                    };
                }

                // 检查名称是否重复（排除自己）
                var existingName = await _context.ZshProcessCategories
                    .AnyAsync(pc => pc.ProcessCategoryName == updateDto.ProcessCategoryName && 
                                   pc.Id != updateDto.Id && !pc.IsDeleted);

                if (existingName)
                {
                    return new ApiResult<ProcessCategoryResultDto>
                    {
                        Code = ApiEnum.Error,
                        Msg = "工序分类名称已存在",
                        Data = null
                    };
                }

                // 更新实体
                processCategory.ProcessCategoryNumber = updateDto.ProcessCategoryNumber;
                processCategory.ProcessCategoryName = updateDto.ProcessCategoryName;
                processCategory.SortOrder = updateDto.SortOrder;
                processCategory.IsActive = updateDto.IsActive;
                processCategory.Remarks = updateDto.Remarks;
                processCategory.UpdateTime = DateTime.Now;
                processCategory.Updator = "System"; // 这里可以从当前用户上下文获取

                await _context.SaveChangesAsync();

                var result = new ProcessCategoryResultDto
                {
                    Id = processCategory.Id,
                    ProcessCategoryNumber = processCategory.ProcessCategoryNumber,
                    ProcessCategoryName = processCategory.ProcessCategoryName,
                    SortOrder = processCategory.SortOrder,
                    IsActive = processCategory.IsActive,
                    Remarks = processCategory.Remarks,
                    ProcessCount = processCategory.Processes?.Count(p => !p.IsDeleted) ?? 0,
                    CreateTime = processCategory.CreateTime,
                    Creator = processCategory.Creator,
                    UpdateTime = processCategory.UpdateTime,
                    Updator = processCategory.Updator
                };

                return new ApiResult<ProcessCategoryResultDto>
                {
                    Code = ApiEnum.Success,
                    Msg = "更新成功",
                    Data = result
                };
            }
            catch (Exception ex)
            {
                return new ApiResult<ProcessCategoryResultDto>
                {
                    Code = ApiEnum.Error,
                    Msg = $"更新失败：{ex.Message}",
                    Data = null
                };
            }
        }

        /// <summary>
        /// 删除工序分类
        /// </summary>
        /// <param name="id">工序分类ID</param>
        /// <returns>删除结果</returns>
        public async Task<ApiResult<bool>> DeleteProcessCategoryAsync(int id)
        {
            try
            {
                var processCategory = await _context.ZshProcessCategories
                    .FirstOrDefaultAsync(pc => pc.Id == id && !pc.IsDeleted);

                if (processCategory == null)
                {
                    return new ApiResult<bool>
                    {
                        Code = ApiEnum.NotFound,
                        Msg = "工序分类不存在",
                        Data = false
                    };
                }

                // 检查是否有关联的工序
                var hasProcesses = await _context.ZshProcesses
                    .AnyAsync(p => p.ProcessCategoryId == id && !p.IsDeleted);

                if (hasProcesses)
                {
                    return new ApiResult<bool>
                    {
                        Code = ApiEnum.Error,
                        Msg = "该工序分类下还有工序，无法删除",
                        Data = false
                    };
                }

                // 软删除
                processCategory.IsDeleted = true;
                processCategory.UpdateTime = DateTime.Now;
                processCategory.Updator = "System"; // 这里可以从当前用户上下文获取

                await _context.SaveChangesAsync();

                return new ApiResult<bool>
                {
                    Code = ApiEnum.Success,
                    Msg = "删除成功",
                    Data = true
                };
            }
            catch (Exception ex)
            {
                return new ApiResult<bool>
                {
                    Code = ApiEnum.Error,
                    Msg = $"删除失败：{ex.Message}",
                    Data = false
                };
            }
        }

        /// <summary>
        /// 获取所有启用的工序分类（用于下拉选择）
        /// </summary>
        /// <returns>工序分类列表</returns>
        public async Task<ApiResult<List<ProcessCategoryResultDto>>> GetActiveProcessCategoriesAsync()
        {
            try
            {
                var processCategories = await _context.ZshProcessCategories
                    .Include(pc => pc.Processes)
                    .Where(pc => !pc.IsDeleted && pc.IsActive)
                    .OrderBy(pc => pc.SortOrder)
                    .ThenBy(pc => pc.ProcessCategoryNumber)
                    .Select(pc => new ProcessCategoryResultDto
                    {
                        Id = pc.Id,
                        ProcessCategoryNumber = pc.ProcessCategoryNumber,
                        ProcessCategoryName = pc.ProcessCategoryName,
                        SortOrder = pc.SortOrder,
                        IsActive = pc.IsActive,
                        Remarks = pc.Remarks,
                        ProcessCount = pc.Processes.Count(p => !p.IsDeleted),
                        CreateTime = pc.CreateTime,
                        Creator = pc.Creator,
                        UpdateTime = pc.UpdateTime,
                        Updator = pc.Updator
                    })
                    .ToListAsync();

                return new ApiResult<List<ProcessCategoryResultDto>>
                {
                    Code = ApiEnum.Success,
                    Msg = "查询成功",
                    Data = processCategories
                };
            }
            catch (Exception ex)
            {
                return new ApiResult<List<ProcessCategoryResultDto>>
                {
                    Code = ApiEnum.Error,
                    Msg = $"查询失败：{ex.Message}",
                    Data = null
                };
            }
        }

        /// <summary>
        /// 导出工序分类到Excel
        /// </summary>
        /// <param name="queryDto">查询条件</param>
        /// <returns>Excel文件字节数组</returns>
        public async Task<byte[]> ExportProcessCategoriesToExcelAsync(ProcessCategoryExportQueryDto queryDto)
        {
            var query = _context.ZshProcessCategories
                .Include(pc => pc.Processes)
                .Where(pc => !pc.IsDeleted)
                .AsQueryable();

            // 应用查询条件
            if (!string.IsNullOrEmpty(queryDto.NumberOrName))
            {
                query = query.Where(pc =>
                    pc.ProcessCategoryNumber.Contains(queryDto.NumberOrName) ||
                    pc.ProcessCategoryName.Contains(queryDto.NumberOrName));
            }

            if (queryDto.IsActive.HasValue)
            {
                query = query.Where(pc => pc.IsActive == queryDto.IsActive.Value);
            }

            // 获取所有数据（不分页）
            var processCategories = await query
                .OrderBy(pc => pc.SortOrder)
                .ThenBy(pc => pc.ProcessCategoryNumber)
                .Select(pc => new ProcessCategoryResultDto
                {
                    Id = pc.Id,
                    ProcessCategoryNumber = pc.ProcessCategoryNumber,
                    ProcessCategoryName = pc.ProcessCategoryName,
                    SortOrder = pc.SortOrder,
                    IsActive = pc.IsActive,
                    Remarks = pc.Remarks,
                    ProcessCount = pc.Processes.Count(p => !p.IsDeleted),
                    CreateTime = pc.CreateTime,
                    Creator = pc.Creator,
                    UpdateTime = pc.UpdateTime,
                    Updator = pc.Updator
                })
                .ToListAsync();

            // 创建Excel工作簿
            var workbook = new XSSFWorkbook();
            var sheet = workbook.CreateSheet("工序分类");

            // 创建标题样式
            var titleStyle = workbook.CreateCellStyle();
            var titleFont = workbook.CreateFont();
            titleFont.FontName = "微软雅黑";
            titleFont.FontHeightInPoints = 12;
            titleFont.IsBold = true;
            titleStyle.SetFont(titleFont);
            titleStyle.Alignment = HorizontalAlignment.Center;
            titleStyle.VerticalAlignment = VerticalAlignment.Center;
            titleStyle.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Grey25Percent.Index;
            titleStyle.FillPattern = FillPattern.SolidForeground;
            titleStyle.BorderBottom = BorderStyle.Thin;
            titleStyle.BorderLeft = BorderStyle.Thin;
            titleStyle.BorderRight = BorderStyle.Thin;
            titleStyle.BorderTop = BorderStyle.Thin;

            // 创建数据样式
            var dataStyle = workbook.CreateCellStyle();
            var dataFont = workbook.CreateFont();
            dataFont.FontName = "微软雅黑";
            dataFont.FontHeightInPoints = 11;
            dataStyle.SetFont(dataFont);
            dataStyle.Alignment = HorizontalAlignment.Left;
            dataStyle.VerticalAlignment = VerticalAlignment.Center;
            dataStyle.BorderBottom = BorderStyle.Thin;
            dataStyle.BorderLeft = BorderStyle.Thin;
            dataStyle.BorderRight = BorderStyle.Thin;
            dataStyle.BorderTop = BorderStyle.Thin;

            // 创建居中样式
            var centerStyle = workbook.CreateCellStyle();
            centerStyle.CloneStyleFrom(dataStyle);
            centerStyle.Alignment = HorizontalAlignment.Center;

            // 创建日期样式
            var dateStyle = workbook.CreateCellStyle();
            dateStyle.CloneStyleFrom(dataStyle);
            dateStyle.DataFormat = workbook.CreateDataFormat().GetFormat("yyyy-mm-dd hh:mm:ss");

            // 创建表头
            var headerRow = sheet.CreateRow(0);
            headerRow.Height = 500; // 设置行高

            var headers = new string[]
            {
                "序号", "工序分类编号", "工序分类名称", "排序", "状态", "工序数量", "备注", "创建人", "创建时间", "更新人", "更新时间"
            };

            for (int i = 0; i < headers.Length; i++)
            {
                var cell = headerRow.CreateCell(i);
                cell.SetCellValue(headers[i]);
                cell.CellStyle = titleStyle;
            }

            // 填充数据
            for (int i = 0; i < processCategories.Count; i++)
            {
                var dataRow = sheet.CreateRow(i + 1);
                var category = processCategories[i];

                // 序号
                var cell0 = dataRow.CreateCell(0);
                cell0.SetCellValue(i + 1);
                cell0.CellStyle = centerStyle;

                // 工序分类编号
                var cell1 = dataRow.CreateCell(1);
                cell1.SetCellValue(category.ProcessCategoryNumber);
                cell1.CellStyle = dataStyle;

                // 工序分类名称
                var cell2 = dataRow.CreateCell(2);
                cell2.SetCellValue(category.ProcessCategoryName);
                cell2.CellStyle = dataStyle;

                // 排序
                var cell3 = dataRow.CreateCell(3);
                cell3.SetCellValue(category.SortOrder);
                cell3.CellStyle = centerStyle;

                // 状态
                var cell4 = dataRow.CreateCell(4);
                cell4.SetCellValue(category.IsActive ? "启用" : "禁用");
                cell4.CellStyle = centerStyle;

                // 工序数量
                var cell5 = dataRow.CreateCell(5);
                cell5.SetCellValue(category.ProcessCount);
                cell5.CellStyle = centerStyle;

                // 备注
                var cell6 = dataRow.CreateCell(6);
                cell6.SetCellValue(category.Remarks ?? "");
                cell6.CellStyle = dataStyle;

                // 创建人
                var cell7 = dataRow.CreateCell(7);
                cell7.SetCellValue(category.Creator ?? "");
                cell7.CellStyle = dataStyle;

                // 创建时间
                var cell8 = dataRow.CreateCell(8);
                cell8.SetCellValue(category.CreateTime);
                cell8.CellStyle = dateStyle;

                // 更新人
                var cell9 = dataRow.CreateCell(9);
                cell9.SetCellValue(category.Updator ?? "");
                cell9.CellStyle = dataStyle;

                // 更新时间
                var cell10 = dataRow.CreateCell(10);
                if (category.UpdateTime.HasValue)
                {
                    cell10.SetCellValue(category.UpdateTime.Value);
                    cell10.CellStyle = dateStyle;
                }
                else
                {
                    cell10.SetCellValue("");
                    cell10.CellStyle = dataStyle;
                }
            }

            // 自动调整列宽
            for (int i = 0; i < headers.Length; i++)
            {
                sheet.AutoSizeColumn(i);
                // 设置最小列宽，避免过窄
                if (sheet.GetColumnWidth(i) < 2000)
                {
                    sheet.SetColumnWidth(i, 2000);
                }
                // 设置最大列宽，避免过宽
                if (sheet.GetColumnWidth(i) > 8000)
                {
                    sheet.SetColumnWidth(i, 8000);
                }
            }

            // 转换为字节数组
            using var memoryStream = new MemoryStream();
            workbook.Write(memoryStream);
            return memoryStream.ToArray();
        }
    }
} 